#include "singleprocesstask.h"

SingleProcesstask::SingleProcesstask(int taskIndex,QString argumentIn,QString input,QString output,bool reVerify,bool delSource)
{
    setAutoDelete(true);


    //或许更好？ 但是用信号让程序看起来乱糟糟的 =(
//    connect(cjxlencoder,static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),this,&SingleProcesstask::Verify);//转换后触发验证
//    connect(jxldecoder,static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),this,&jxlEncoder::hashVerify);//转换后触发验证

    //don't ask why
    index=taskIndex;
    argument=argumentIn;
    inputTarget=input;
    outputTarget=output;
    Flag_reVerify=reVerify;
    Flag_delSource=delSource;
}

SingleProcesstask::~SingleProcesstask()
{

}

//线程执行内容
void SingleProcesstask::run()
{
    //必须在这里new，构造函数new出来仍然归属于主线程
    cjxlencoder=new QProcess();
    jxldecoder=new QProcess();

    //====================启动外部程序====================
    cjxlencoder->setNativeArguments(argument);
    cjxlencoder->start(cjxlFilename);

    //====================阻塞当前线程到JXL转换完毕========
    cjxlencoder->waitForFinished(-1);

    //====================后处理=========================
    QString result=cjxlencoder->readAllStandardError();//实测Output无效，Error有效

    emit convertLog(result);
    //ui->plainTextEdit->appendPlainText(result);

    bool errorLog=result.contains("error",Qt::CaseInsensitive)||result.contains("failed",Qt::CaseInsensitive)||result.contains("couldn't",Qt::CaseInsensitive);

    if(QFile::exists(outputTarget)&&!errorLog)
    {
        if(Flag_reVerify)//开启二次验证，重新生成jpg
        {
            QString tempOutput=inputTarget+".jpg";
            while(QFile::exists(tempOutput)){//重名文件重命名 这仍然有可能因为找不到合适的文件名而卡死，但是在windows系统几乎是不可能的
                tempOutput=inputTarget+"("+QString::number(QRandomGenerator::global()->generate())+").jpg";
            }
            //qDebug()<<tempOutput;

            QString argument='"'+outputTarget+'"'+" "+'"'+tempOutput+'"';//文件名加引号，防止文件名含空格

            //====================启动外部程序====================
            jxldecoder->setNativeArguments(argument);
            jxldecoder->start(djxlFilename);

            //====================阻塞当前线程到JXL转换完毕========
            jxldecoder->waitForFinished(-1);

            //====================后处理验证==================
            QFile sFile(inputTarget);//原始文件
            QFile dFile(tempOutput);//二次转换后的文件
            QByteArray sFiledata;
            QByteArray dFiledata;


            if(sFile.open(QIODevice::ReadOnly)&&dFile.open(QIODevice::ReadOnly))
            {
                //读取文件
                while (!sFile.atEnd()) {
                    sFiledata.append(sFile.readAll());
                    //sHash.addData(sFile.readAll());
                }
                while (!dFile.atEnd()) {
                    dFiledata.append(dFile.readAll());
                    //dHash.addData(dFile.readAll());
                }
                sFile.close();
                //QByteArray sHashResult= sHash.result();//对比哈希值，未使用，采用直接对比文件的方式
                //QByteArray dHashResult= dHash.result()
                //if(sHashResult==dHashResult){
                if(sFiledata==dFiledata){//文件内容一致
                    emit convertLog("\njxlgui:Secondary verify sucessed.\n");
                }
                else {
                    emit convertLog("\njxlgui:Hash verify failed.\n");
                    emit convertResult(index,2);

                    //not good
                    sFile.close();
                    dFile.remove();//删除用于验证的jpg
                    return;//验证失败，直接退出，不删除原文件
                }
            }
            else{
                emit convertLog("\njxlgui:Hash verify failed.\n");
                emit convertResult(index,2);

                sFile.close();
                dFile.remove();//删除用于验证的jpg
                return;//直接退出，不执行删除
            }

            sFile.close();
            dFile.remove();//删除用于验证的jpg
        }

        if(Flag_delSource){
            if(QFile::remove(inputTarget)){
                emit convertLog("\njxlgui:"+inputTarget+" deleted\n");
            }
            else {
                emit convertLog("\njxlgui:"+inputTarget+" delete failed\n");
            }
        }

        emit convertResult(index,1);

    }
    else {
        emit convertResult(index,0);
    }
}
